package com.easpeed.elevator.serialportwash;

import android.os.HandlerThread;
import android.serialport.SerialPort;
import android.util.Log;
import com.bigyu.utils.Logger;

import com.easpeed.elevator.utils.ByteUtil;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.Scheduler;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;

/**
 * Created by Administrator on 2017/3/28 0028.
 */
public class SerialPortManager3 {

    private static final String TAG = "SerialPortManager";

    private SerialReadThread3 mReadThread;
    private OutputStream mOutputStream;
    private HandlerThread mWriteThread;
    private Scheduler mSendScheduler;

    private static class InstanceHolder {

        public static SerialPortManager3 sManager = new SerialPortManager3();
    }

    public static SerialPortManager3 instance() {
        return InstanceHolder.sManager;
    }

    private SerialPort mSerialPort;

    private SerialPortManager3() {
    }

    /**
     * 打开串口
     *
     * @param device2
     * @return
     */
    public SerialPort open(Device3 device2) {
        return open(device2.getPath(), device2.getBaudrate());
    }

    /**
     * 打开串口
     *
     * @param devicePath
     * @param baudrateString
     * @return
     */
    public SerialPort open(String devicePath, String baudrateString) {
        if (mSerialPort != null) {
            close();
        }
        try {
            File device = new File(devicePath);
            int baurate = Integer.parseInt(baudrateString);
            // 默认8N1(8数据位、无校验位、1停止位)
            mSerialPort = SerialPort.newBuilder(device, baurate).build();
            mReadThread = new SerialReadThread3(mSerialPort.getInputStream());

            mReadThread.start();

            mOutputStream = mSerialPort.getOutputStream();

            mWriteThread = new HandlerThread("write-thread");
            mWriteThread.start();
            mSendScheduler = AndroidSchedulers.from(mWriteThread.getLooper());

            return mSerialPort;
        } catch (Throwable tr) {
            Logger.e(TAG, "打开串口失败"+ tr);
            close();
            return null;
        }
    }

    /**
     * 关闭串口
     */
    public void close() {
        if (mReadThread != null) {
            mReadThread.close();
        }
        if (mOutputStream != null) {
            try {
                mOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (mWriteThread != null) {
            mWriteThread.quit();
        }

        if (mSerialPort != null) {
            mSerialPort.close();
            mSerialPort = null;
        }
    }

    /**
     * 发送数据
     *
     * @param datas
     * @return
     */
    public void sendData(byte[] datas) throws Exception {
        mOutputStream.write(datas);
    }

    /**
     * (rx包裹)发送数据
     *
     * @param datas
     * @return
     */
    private Observable<Object> rxSendData(final byte[] datas) {

        return Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
                try {
                    sendData(datas);
                    emitter.onNext(new Object());
                } catch (Exception e) {

                    Logger.e("oye", "发送：" + ByteUtil.bytes2HexStr(datas) + " 失败");

                    if (!emitter.isDisposed()) {
                        emitter.onError(e);
                        return;
                    }
                }
                emitter.onComplete();
            }
        });
    }

    /**
     * 发送命令包
     */
    public void sendCommand(final byte[] command) {

        // TODO: 2018/3/22  
        Logger.e("oye", "发送命令：");
        rxSendData(command).subscribeOn(mSendScheduler).subscribe(new Observer<Object>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Object o) {
            }

            @Override
            public void onError(Throwable e) {
                Logger.e("oye", "发送失败：" + e.toString());
            }

            @Override
            public void onComplete() {

            }
        });
    }
}
